export class Controller {
    constructor() {
        this.root = {
            children: new Map(),
            handler: null,
            args: []
        };
    }
    /**
     * 
     * @param {string} name 
     * @param {Function} handler 
     * @param  {...any} args 
     */
    on(name, handler, ...args) {
        if (!name) {
            this.root.handler = handler;
            this.root.args = args;
            return;
        }
        let node = this.root;
        let keys = name.split('-');
        for (let key of keys) {
            if (!node.children) {
                node.children = new Map();
            }
            let nNode = node.children.get(key);
            if (!nNode) {
                nNode = { children: null, handler: null, args: [] };
                node.children.set(key, nNode);
            }
            node = nNode;
        }
        node.handler = handler;
        node.args = args;
        return this;
    }

    emit(name, ...args) {
        let node = this.find(name);
        node?.handler?.(...node.args, ...args);
        return this;
    }

    off(name) {
        let node = this.find(name);
        if (node) {
            node.children?.clear();
            node.handler = null;
            node.args.length = 0;
        }
        return this;
    }

    clear() {
        this.root.children.clear();
        this.root.handler=null;
        this.root.args.length=0;
    }

    find(name) {
        if (!name) {
            return this.root;
        }
        let keys = name.split('-');
        let node = this.root;
        for (let key of keys) {
            if (!node) return null;
            node = node.children?.get(key);
        }
        return node;
    }
}